package com.douyinkan.service;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.io.File;

@Service
public class DataSourceManagerService {

    private static final Logger logger = LoggerFactory.getLogger(DataSourceManagerService.class);

    @Autowired
    private DatabaseService databaseService;

    @Autowired
    private Environment env;

    private volatile DataSource currentDataSource = null;
    private String currentDbPath = null;

    /**
     * 根据媒体目录获取或创建数据源
     *
     * @param mediaDir 媒体目录路径
     * @return 对应媒体目录的数据源对象
     */
    public DataSource getOrCreateDataSource(String mediaDir) {
        logger.info("=== Getting or creating data source for media directory: {} ===", mediaDir);
        String dbPath = getDatabasePath(mediaDir);
        logger.debug("Database path for media directory {}: {}", mediaDir, dbPath);

        // 检查是否是当前数据源，避免频繁切换
        if (currentDataSource != null && dbPath.equals(currentDbPath)) {
            logger.debug("Reusing current data source for: {}", dbPath);
            return currentDataSource;
        }

        logger.info("Creating new data source for: {}", dbPath);
        HikariDataSource dataSource = createDataSource(dbPath);

        // 初始化数据库模式
        logger.info("Initializing database schema for data source: {}", dbPath);
        try {
            databaseService.initializeDatabaseSchema(dataSource);
            logger.info("Database schema initialized for data source: {}", dbPath);

            // 验证表是否创建成功
            logger.debug("Verifying database tables creation");
            try (java.sql.Connection conn = dataSource.getConnection();
                 java.sql.Statement stmt = conn.createStatement()) {
                stmt.execute("PRAGMA table_info(content)");
                logger.debug("Content table verified to exist in database: {}", dbPath);
            } catch (Exception e) {
                logger.warn("Could not verify content table existence in database: {}", dbPath, e);
            }
        } catch (Exception e) {
            logger.error("Failed to initialize database schema for data source: {}", dbPath, e);
            throw new RuntimeException("Failed to initialize database schema for data source: " + dbPath, e);
        }

        // 更新当前数据源
        this.currentDataSource = dataSource;
        this.currentDbPath = dbPath;

        logger.info("=== Successfully set data source for media directory: {} ===", mediaDir);
        return dataSource;
    }

    /**
     * 创建SQLite数据源
     */
    private HikariDataSource createDataSource(String dbPath) {
        logger.info("Creating SQLite data source with path: {}", dbPath);
        // 确保数据库目录存在
        File dbFile = new File(dbPath);
        File parentDir = dbFile.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            logger.info("Creating database parent directory: {}", parentDir.getAbsolutePath());
            parentDir.mkdirs();
        }

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:sqlite:" + dbPath);
        config.setDriverClassName("org.sqlite.JDBC");
        config.setMaximumPoolSize(10);
        config.setMinimumIdle(2);
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        config.setMaxLifetime(1800000);
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.addDataSourceProperty("journal_mode", "WAL"); // SQLite WAL模式，提高并发性能

        logger.debug("HikariConfig settings: JDBC URL={}, Max Pool Size={}, Min Idle={}",
                    config.getJdbcUrl(), config.getMaximumPoolSize(), config.getMinimumIdle());

        HikariDataSource dataSource = new HikariDataSource(config);
        logger.info("Successfully created HikariDataSource for: {}", dbPath);
        return dataSource;
    }

    /**
     * 根据媒体目录获取数据库路径
     */
    private String getDatabasePath(String mediaDir) {
        String metaDir = getMediaMetaDir(mediaDir);
        String dbPath = metaDir + "/content.db";
        logger.debug("Computed database path for media directory {}: {}", mediaDir, dbPath);
        return dbPath;
    }

    /**
     * 根据媒体目录获取元数据目录
     */
    private String getMediaMetaDir(String mediaDir) {
        String metaDir = mediaDir + "/myMediaMeta";
        logger.debug("Computed meta directory for media directory {}: {}", mediaDir, metaDir);
        return metaDir;
    }

    /**
     * 获取当前数据源
     */
    public DataSource getCurrentDataSource() {
        return currentDataSource;
    }

    /**
     * 获取当前数据库路径
     */
    public String getCurrentDbPath() {
        return currentDbPath;
    }
}